﻿using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Quartz;
using RayD.Core;
using RayD.App.SystemModule;

namespace RayD.App.Quartz
{
    public class QuartzService : IHostedService, IDisposable
    {
        private readonly ILogger<QuartzService> _logger;
        private IScheduler _scheduler;
        private JobApp _jobService;

        public QuartzService(ILogger<QuartzService> logger, IScheduler scheduler, JobApp jobService)
        {
            _logger = logger;
            _scheduler = scheduler;
            _jobService = jobService;
        }

        public Task StartAsync(CancellationToken cancellationToken)
        {
            //启动定时job，可以在这里配置读取数据库需要启动的任务，然后启动他们
            var jobList = _jobService
                .GetList(null)
                .Where(c => 
                    c.B_EnabledMark == EnabledMark.Enabled && 
                    c.B_JobTerminal == AppSettings.JobOption.SubjectTerminal
                );
            foreach (var job in jobList)
            {
                var jobBuilderType = typeof(JobBuilder);
                var method = jobBuilderType.GetMethods().FirstOrDefault(
                        x => x.Name.Equals("Create", StringComparison.OrdinalIgnoreCase) &&
                             x.IsGenericMethod && x.GetParameters().Length == 0)
                    ?.MakeGenericMethod(Type.GetType(job.B_JobCall));

                var jobBuilder = (JobBuilder)method.Invoke(null, null);

                IJobDetail jobDetail = jobBuilder.WithIdentity(job.B_Id).Build();
                jobDetail.JobDataMap[Define.JOBMAPKEY] = job.B_Id;  //传递job信息
                ITrigger trigger = TriggerBuilder.Create()
                    .WithCronSchedule(job.B_Cron)
                    .WithIdentity(job.B_Id)
                    .StartNow()
                    .Build();
                _scheduler.ScheduleJob(jobDetail, trigger);
            }
            _scheduler.Start();
            return Task.CompletedTask;
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            _scheduler.Shutdown();
            _logger.LogInformation("关闭定时job");
            return Task.CompletedTask;
        }

        public void Dispose()
        {
            throw new NotImplementedException();
        }
    }
}
